/*
 * Copyright (c) 2023, LXMS (lxinet.cn).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.lxinet.lxms.system.service;

import cn.lxinet.lxms.framework.core.utils.Assert;
import cn.lxinet.lxms.framework.core.utils.StringUtils;
import cn.lxinet.lxms.framework.mybatis.service.SimpleService;
import cn.lxinet.lxms.system.entity.SysDept;
import cn.lxinet.lxms.system.mapper.SysDeptMapper;
import cn.lxinet.lxms.system.message.SystemErrorCode;
import cn.lxinet.lxms.system.vo.SysDeptVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 部门
 *
 * @author zcx
 * @date 2023/07/08
 */
@Slf4j
@Service
public class SysDeptService extends SimpleService<SysDept> {
    public static final String PATHS_SEPARATOR = "/";

    @Autowired
    private SysDeptMapper sysDeptMapper;

    /**
     * 列表
     *
     * @param name     名称
     * @param parentId 父id
     * @param status   状态
     * @return {@link List}<{@link SysDeptVo}>
     */
    public List<SysDeptVo> list(String name, Long parentId, Integer status){
        List<SysDeptVo> allList = sysDeptMapper.list(name, parentId, status);
        //如果关键词搜索，直接返回列表，不组装树形结构数据
        if (StringUtils.isNotBlank(name)){
            return allList;
        }
        //获取一级部门
        List<SysDeptVo> deptList = allList.stream().filter(dept -> dept.getParentId() == 0).toList();
        genDept(deptList, allList);
        return deptList;
    }

    /**
     * 选择框列表
     *
     * @return {@link List}<{@link SysDeptVo}>
     */
    public List<SysDeptVo> simpleList(){
        List<SysDeptVo> allList = sysDeptMapper.simpleList();
        //获取一级部门
        List<SysDeptVo> deptList = allList.stream().filter(dept -> dept.getParentId() == 0).toList();
        genDept(deptList, allList);
        return deptList;
    }

    private void genDept(List<SysDeptVo> deptList, List<SysDeptVo> allList){
        deptList.forEach(dept -> {
            List<SysDeptVo> children = allList.stream().filter(d -> d.getParentId() == dept.getId()).toList();
            if (children.size() > 0){
                dept.setChildren(children);
                genDept(children, allList);
            }
        });
    }

    public void add(SysDept sysDept){
        String paths = PATHS_SEPARATOR;
        sysDept.setParentId(sysDept.getParentId() == null ? 0L : sysDept.getParentId());
        if (sysDept.getParentId() > 0){
            SysDept parent = findById(sysDept.getParentId());
            Assert.notNull(parent, SystemErrorCode.PARENT_DEPT_NOT_EXIST);
            paths = parent.getPaths() + PATHS_SEPARATOR;
        }
        super.insert(sysDept);
        sysDeptMapper.updatePaths(sysDept.getId(), paths + sysDept.getId());
    }

    public void update(SysDept sysDept){
        SysDept dbSysDept = findById(sysDept.getId());
        Assert.notNull(dbSysDept, SystemErrorCode.DEPT_NOT_EXIST);
        if (!dbSysDept.getParentId().equals(sysDept.getParentId())){
            if (sysDept.getParentId() > 0){
                SysDept parent = findById(sysDept.getParentId());
                Assert.notNull(parent, SystemErrorCode.PARENT_DEPT_NOT_EXIST);
                sysDept.setPaths(parent.getPaths() + PATHS_SEPARATOR + sysDept.getId());
            }else {
                sysDept.setPaths(PATHS_SEPARATOR + sysDept.getId());
            }
        }
        super.updateById(sysDept);
    }

    public void delete(Long id){
        super.deleteById(id);
        sysDeptMapper.delSonDept(PATHS_SEPARATOR + id + PATHS_SEPARATOR);
    }

    public List<Long> listSonIds(@Param("id") Long id){
        return sysDeptMapper.listSonIds(id);
    }
}